package com.linjiahao.nettyBus.handler;

import cn.hutool.core.util.URLUtil;
import com.linjiahao.commonall.constant.AuthConstant;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.util.AttributeKey;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;


/**
 * @Author Shinelon
 * @Date 2023/1/11 0:40
 * @Version 1.0
 */
@Slf4j
@Component
@ChannelHandler.Sharable
public class NettyWebSocketAuthHandler extends ChannelInboundHandlerAdapter {

    private final String headerKey = "Sec-WebSocket-Protocol";




    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        //解析headers上的token放到channel中
        String token = "";
        if(msg instanceof FullHttpRequest){
            FullHttpRequest request = (FullHttpRequest) msg;
            String userId = request.headers().get(AuthConstant.AUTH_HEADER);
            token = request.headers().get(AuthConstant.SUB_PROTOCOL);
            String uri = request.getUri();
            log.info("Auth获取的uri为:{},userId为:{},token为：{}",uri,userId,token);
            if(StringUtils.isNotBlank(userId)){
                log.info("Auth成功,userId:{}",userId);
                AttributeKey<String> auth = AttributeKey.valueOf("userId");
                ctx.channel().attr(auth).set(userId);
            }
            request.setUri(URLUtil.getPath(uri));
        }
        //用于处理websocket, /ws为访问websocket时的uri,同时设置子协议
        handlerAdded(ctx,token);
        super.channelRead(ctx,msg);
    }


    public void handlerAdded(ChannelHandlerContext ctx,String token) {
        ChannelPipeline cp = ctx.pipeline();
        if (cp.get(WebSocketServerProtocolHandler.class) == null) {
            ctx.pipeline().addLast("ProtocolHandler", new WebSocketServerProtocolHandler("/nettyBus", token,true));
            ctx.pipeline().addLast(new NettyWebSocketHandler());
            ctx.pipeline().remove(this.getClass());
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.info("NettyWebSocketAuthHandler异常:{}",cause);
    }

}
